package fem2d;

import math2.MathUtilities;
import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.Element;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Observer;
import fem2.StringUtilities;
import fem2.element.StructuralElement;
import fem2.enu.State;
import fem2.material.FluencyCriteria;
import fem2.material.LemaitreDamageMM2;
import fem2.observer.GidDamageObserver;
import fem2.observer.GidPlasticityObserver;
import fem2.observer.GidStrainObserver;
import fem2.observer.TimeStepObserver;
import fem2.strategies.Strategy;

public class LshapeLemaitre extends AbstractStructuralStaticDemo {

	public LshapeLemaitre() {
		projectDir = "/home/hbui/kratos_janosch";
		projectName = "Lshape.gid";
		meshFileName = "structured_mesh_lemaitre";
	}

	@Override
	public Mesh createMesh() {
		return new Lshape().createMesh();
	}

	@Override
	public Model createConditions(Model m) {
		Mesh mesh = m.getMesh();
		Constraint c1 = new Constraint(false, false);
		Constraint c2 = new Constraint(true, false);
		c2.setValue(1, -20);
		mesh.setConstraint(c1, MeshUtilities.seekNodesOnSurface(mesh, 0, 1, -1000));
		MeshUtilities.seekNode(mesh, 1000, 500).setConstraint(c2);
		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 210e3;
		double nu = 0.3;
		double t = 1.0;
		double r = 3.5;
		double s = 1.0;

		FluencyCriteria isotropicHardeningRule = new FluencyCriteria() {

			@Override
			public double computeFluencyValue(double v) {
				return 620 + 3300 * (1 - Math.exp(-0.4 * v));
			}

			@Override
			public double computeFluencyDerivative(double v) {
				return 3300 * 0.4 * Math.exp(-0.4 * v);
			}
		};

		return new LemaitreDamageMM2(E, nu, t, 0, State.PLANE_STRAIN, isotropicHardeningRule, r, s);

	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		Element e = new StructuralElement(mp, mm);
		// e.setEchoLevel(EchoLevelType.AUX4);
		return e;
	}

	@Override
	public void addObservers(Model m, Strategy s, TimeStepObserver o) {
		super.addObservers(m, s, o);

		String meshName = StringUtilities.getFileName(meshFileName);

		Observer po = new GidPlasticityObserver(m, o, projectDir, projectName, meshName);
		Observer so = new GidStrainObserver(m, o, projectDir, projectName, meshName);
		Observer do1 = new GidDamageObserver(m, o, projectDir, projectName, meshName);

		s.addObserver(so);
		s.addObserver(po);
		s.addObserver(do1);
	}

	public static void main(String[] args) {
		AbstractStructuralStaticDemo demo = new LshapeLemaitre();

		double[] lambda = MathUtilities.createLambdaArray(0, 0.005, 1);

		demo.run(lambda);

	}
}
